#include <xp/net/sttp.h>
#include <xp/net/socket.h>
#include <xp/bas/memory.h>
#include <xp/bas/locale.h>
#include <xp/bas/stdlib.h>
#include <xp/bas/stdio.h>
#include <xp/bas/time.h>
#include <xp/bas/errno.h>
#include <xp/bas/signal.h>
#include <xp/bas/endian.h>

#ifndef _WIN32
	#include <arpa/inet.h>
#endif

#ifdef __linux
	#include <mcheck.h>
#endif

int quit = 0;

void set_quit (int sig)
{
	xp_signal (SIGINT, SIG_IGN);
	quit = 1;
	xp_signal (SIGINT, set_quit);
}

int xp_main (int argc, xp_char_t* argv[])
{
	int handle;
	xp_uint16_t port;
	struct sockaddr_in sin;
	xp_str_t cmd;
	xp_size_t count = 0;
	xp_sttp_t sttp;
	xp_time_t start, end;

	long max;
	long zzz = 0;

#ifdef __linux
	mtrace ();
#endif

	xp_setlocale ();
	xp_signal (SIGINT, set_quit);

	if (argc != 4) {
		xp_printf (XP_TEXT("usage: %s host port max\n"), argv[0]);
		return -1;
	}

	if (xp_sckstartup() == -1) {
		xp_printf (XP_TEXT("can't startup socket subsystem\n"));
		return -1;
	}

	if ((handle = xp_sckopen(PF_INET, SOCK_STREAM, 0)) == -1) {
		xp_printf (XP_TEXT("can't create socket\n"));
		xp_sckcleanup ();
		return -1;
	}

	XP_STRTOI (max, argv[3], XP_NULL, 10);
	XP_STRTOI (port, argv[2], XP_NULL, 10);

	xp_memset (&sin, 0, xp_sizeof(sin));
	sin.sin_family = AF_INET;
#ifdef XP_CHAR_IS_WCHAR
	{
		xp_mchar_t host[1000];
		xp_wcstomcs (argv[1], host, xp_countof(host));
		sin.sin_addr.s_addr = inet_addr (host);
	}
#else
	sin.sin_addr.s_addr = inet_addr (argv[1]);
#endif
	sin.sin_port = xp_hton16 (port);

	if (xp_sckconn (handle, 
		(xp_sckadr_t*)&sin, (xp_scklen_t)xp_sizeof(sin), -1) == -1) {
		xp_printf (XP_TEXT("can't connect\n"));
		xp_sckclose (handle);
		xp_sckcleanup ();
		return -1;
	}

	xp_str_open (&cmd, 256);
	xp_sttp_open (&sttp, handle);

	xp_gettime (&start);

	while (!quit && zzz < max) {
		//const xp_char_t* p;

		xp_sttp_send (&sttp, XP_TEXT("TEST"), 1,
			XP_TEXT("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb]"));

		if (xp_sttp_recv (&sttp, &cmd, &count) == -1) {
			xp_printf (XP_TEXT("sttp error - %d\n"), sttp.errnum);
			break;
		}

		/*
		p = cmd.buffer;
		while (count > 0) {
#ifdef _WIN32
			MessageBox (XP_NULL, p, XP_TEXT("sttp"), MB_OK);
#else
			xp_printf (XP_TEXT("%s\n"), p);	
#endif
			p += xp_strlen(p) + 1;
			count--;
		}
		*/

		zzz++;
	}
	xp_gettime (&end);

	xp_str_close (&cmd);
	xp_sttp_close (&sttp);

	xp_sckclose (handle);
	xp_sckcleanup ();

	xp_printf (XP_TEXT("zzz = %lu, max = %lu, lapse = %lu\n"), 
		zzz, max, (unsigned long)((end - start) / 1000));
#ifdef __linux
	muntrace ();
#endif
	return 0;
}
